/* Project eeprom_877
PIC16F877A
*/

#include <pic.h>

__CONFIG(
PWRTEN
& BORDIS
& UNPROTECT
& WDTDIS
& LVPDIS
& HS
);

__IDLOC(F877);

#define E RB2
#define RS RB3
#define RW RB1

#define sw0 RE1
#define sw1 RE0

#define XON 17
#define XOFF 19

unsigned char xf;
unsigned char rbuf[16];
unsigned char wp;
unsigned char rp;
unsigned char dc;

unsigned char N, sw, sww, ADN, ADN0;
unsigned char ADVH, ADVL, ADVHR, ADVLR;
unsigned char ADIH, ADIL, ADIHR, ADILR;

unsigned int ii;
unsigned char n, m, j;


// 割り込み関数

void interrupt entry(void){
unsigned char c;

if(RCIF){
c = RCREG;
if(c == XON || c == XOFF){
xf = c;
return;
}
if(dc == 16) return;
rbuf[wp] = c;
wp++;
wp &= 15;
dc++;
if(dc == 12){
while(TXIF == 0);
TXREG = XOFF;
}
}

if(INTF){
INTF = 0;
sw = 1;
}

if(RBIF){
RBIF = 0;
sww = 1;
}
}


// シリアル通信関数群

unsigned char getchr(void){
unsigned char c;

while(dc == 0);
RCIE = 0;
c = rbuf[rp];
rp++;
rp &= 15;
dc --;
if(dc == 12){
while(TXIF == 0);
TXREG = XON;
}
RCIE = 1;
return(c);
}

void putchr(unsigned char c){
while(xf == XOFF);
while(TXIF == 0);
TXREG = c;
}

void put(const unsigned char *s){
while(*s) putchr(*s++);
}


void putv(int v){
char i;
char buf[5];
v *=33;
for(i=0;i<5;i++)
buf[i]='0';
i=4;
do{
buf[i]=(v%10)+'0';
v=v/10;
i--;
} while(v>0);
putchr(buf[0]);
putchr('.');
for(i=1;i<4;i++)
putchr(buf[i]);
}


void puti(int v){
char i;
char buf[5];
v *=5;
for(i=0;i<5;i++)
buf[i]='0';
i=4;
do{
buf[i]=(v%10)+'0';
v=v/10;
i--;
} while(v>0);
putchr(buf[1]);
putchr(buf[2]);
putchr(buf[3]);
putchr('.');
putchr(buf[4]);
}


// LCD表示関数群

void lcd_w_com4(unsigned char d){
RS = 0;
RW = 0;
PORTD = d << 4;
E = 1; NOP();
E = 0;
}

void lcd_w_chr4(unsigned char d){
RS = 1;
RW = 0;
PORTD = d << 4;
E = 1; NOP();
E = 0;
}

void lcd_bfck(void){
unsigned char d;

PORTD = 0;
TRISD7 = 1;
RS = 0;
RW = 1;

do{
E = 1; NOP();
d = RD7;
E = 0;
NOP(); NOP();
E = 1; NOP();
E = 0;
NOP(); NOP();
} while(d);

PORTD = 0;
TRISD7 = 0;
}


void lcd_putcom(unsigned char d){
lcd_bfck();
lcd_w_com4(d >> 4);
lcd_w_com4(d);
}

void lcd_locate(
unsigned char x, unsigned char y){
lcd_putcom((x + 0x40 * y) | 0x80);
}

void lcd_putchr(unsigned char d){
lcd_bfck();
lcd_w_chr4(d >> 4);
lcd_w_chr4(d);
}

void lcd_puts(const unsigned char *s){
while(*s) lcd_putchr(*s++);
}

void lcd_lclr(unsigned char d){
unsigned char i;
lcd_locate(0, d);
for(i=0; i<40; i++)
lcd_putchr(' ');
lcd_locate(0, d);
}

void lcd_putv(int v){
char i;
char buf[5];
v *=33;
for(i=0;i<5;i++)
buf[i]='0';
i=4;
do{
buf[i]=(v%10)+'0';
v=v/10;
i--;
} while(v>0);
lcd_putchr(buf[0]);
lcd_putchr('.');
for(i=1;i<4;i++)
lcd_putchr(buf[i]);
}


void lcd_puti(int v){
char i;
char buf[5];
v *=5;
for(i=0;i<5;i++)
buf[i]='0';
i=4;
do{
buf[i]=(v%10)+'0';
v=v/10;
i--;
} while(v>0);
lcd_putchr(buf[1]);
lcd_putchr(buf[2]);
lcd_putchr(buf[3]);
lcd_putchr('.');
lcd_putchr(buf[4]);
}


void lcd_putui(
unsigned int ui, unsigned char d){
char i;
unsigned char buf[5];
for(i=0; i<10; i++) buf[i] = ' ';
i = 4;
do{
buf[i] = (ui % 10) + '0';
ui = ui / 10;
i--;
} while(ui > 0);
for(i=(5-d); i<5; i++) lcd_putchr(buf[i]);
}



// メイン関数

void main(void){

unsigned int v, v0, vv;

OPTION = 0b10000111;
CMCON = 0b00000111;

PORTA = 0;
TRISA = 0b00001011;
ADCON1 = 0b10000101;

PORTB = 0;
TRISB = 0b00100001;
PORTC = 0;
TRISC = 0b10000000;
PORTD = 0;
TRISD = 0b00000000;
PORTE = 0;
TRISE = 0b00000011;

INTCON = 0b11011000;
PIE1 = 0b00100000;
INTF = 0;
RBIF = 0;

SPBRG = 128;
TXSTA = 0b00100100;
RCSTA = 0b10010000;

wp = 0;
rp = 0;
dc = 0;
xf = XON;

RCIE = 1;
PEIE = 1;
ei();


TMR0 = 0; while(TMR0 < 255);
lcd_w_com4(0x03);
TMR0 = 0; while(TMR0 < 80);
lcd_w_com4(0x03);
TMR0 = 0; while(TMR0 < 2);
lcd_w_com4(0x03);
TMR0 = 0; while(TMR0 < 2);
lcd_w_com4(0x02);

lcd_putcom(0x28);
lcd_putcom(0x01);
lcd_putcom(0x0c);


N = 0;
sw = 0; sww = 0;



while(1){



if(sw){
for(n=0; n<84; n++){
eeprom_write(n, 0);
}
N = 0;
sw = 0;
}


if(sww){
sww = 0;
put("\n");
put(" volt(V) ");
put(" ampere(mA)");
put("\n");
put("\n");

ADN = eeprom_read(0);
for(m=0; m<ADN; m++){
ADVHR = eeprom_read(m*4 + 1);
ADVLR = eeprom_read(m*4 + 2);
vv = ADVHR*256 + ADVLR;
put(" ");
putv(vv);
ADIHR = eeprom_read(m*4 + 3);
ADILR = eeprom_read(m*4 + 4);
vv = ADIHR*256 + ADILR;
put(" ");
puti(vv);
put("\n");
}
}



for(j=0; j<15; j++){

ADCON0 = 0b10000001;
TMR0 = 0;
while(TMR0 < 2);
GODONE = 1;
while(GODONE);
v = (ADRESH*256)+ADRESL;
v0 = v;

lcd_lclr(0);
lcd_locate(0, 0);
lcd_puts(" CH0 N=");
ADN0 = eeprom_read(0);
lcd_putui(ADN0, 2);

lcd_lclr(1);
lcd_locate(0, 1);
lcd_puts(" ");
lcd_putv(v0);
lcd_puts("V");

ADCON0 = 0b10001001;
TMR0 = 0;
while(TMR0 < 2);
GODONE = 1;
while(GODONE);
v = (ADRESH*256)+ADRESL;
v0 = v;

lcd_locate(7, 1);
lcd_puts(" ");
lcd_puti(v0);
lcd_puts("mA");



if(sw1 == 0){
for(ii=0; ii<25; ii++){
TMR0 = 0;
while(TMR0 < 240);
}
} else {
for(ii=0; ii<300; ii++){
TMR0 = 0;
while(TMR0 < 255);
}
}
}

if(sw0){
if(N < 20){

ADCON0 = 0b10000001;
TMR0 = 0;
while(TMR0 < 2);
GODONE = 1;
while(GODONE);
ADVH = ADRESH;
ADVL = ADRESL;
eeprom_write(0, N + 1);
eeprom_write(N*4 + 1, ADVH);
eeprom_write(N*4 + 2, ADVL);

ADCON0 = 0b10001001;
TMR0 = 0;
while(TMR0 < 2);
GODONE = 1;
while(GODONE);
ADIH = ADRESH;
ADIL = ADRESL;
eeprom_write(N*4 + 3, ADIH);
eeprom_write(N*4 + 4, ADIL);
}
N++;
}
}
}